﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Mail;
using WarOfDev.EF;
using System.Data.Entity;
using WarOfDev.Core;
using WarOfDev.Core.Common;

namespace WarOfDev.AutoTasks.Mail
{
    public class MailService:IExecutable
    {
        public MailService()
        {
            smtpService = new SmtpClient();
            smtpService.UseDefaultCredentials = false;
            NetworkCredential auth=new NetworkCredential("warofdev@gmail.com","warofdev");
            smtpService.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpService.Credentials = auth;
            smtpService.EnableSsl = true;
            smtpService.Port = 25;
            smtpService.Host = "smtp.gmail.com";

            db = new WarDevEntities();
        }

        private MailAddress fromAddress = new MailAddress("message@warofdev.com");
        private SmtpClient smtpService;
        private WarDevEntities db;
            

        private List<MailQueue> CheckStatus()
        {
            return db.MailQueues.Where(q => q.Status <= (int)EnumMailQueueStatus.Sent).ToList();
        }


        public void Execute()
        {
            var queue=CheckStatus();
            if (queue == null || queue.Count == 0) return;

            foreach (var q in queue)
            {
                switch (q.MailType)
                {
                    case (int)EnumMailQueueType.NewPuzzle:
                    {
                        SendNewPuzzleEmail(q);
                        break;    
                    }
                    case (int)EnumMailQueueType.NewCate:
                    {
                        SendNewPuzzleEmail(q);
                        break;
                    }
                }
            }
        }

        private void ReplacePostTemplateContent(Post post,StringBuilder sb)
        {
            if (post.PostType == (int)EnumPostType.Puzzle)
            {
                sb.Replace("$PuzzleTitle$", post.Title);
                sb.Replace("$PuzzleLink$", "");
                sb.Replace("$PuzzleOnwer$", post.Developer.NickName);
                sb.Replace("$PuzzleContent$", post.Content);
                sb.Replace("$PuzzleTags$", post.Tags);
                sb.Replace("$PuzzleExperience$", post.ExperienceValue.ToString());
            }
            else
            {
                sb.Replace("$CateTitle$", post.Title);
                sb.Replace("$CateLink$", "");
                sb.Replace("$CateOnwer$", post.Developer.NickName);
                sb.Replace("$CateContent$", post.Content);
                sb.Replace("$CateTags$", post.Tags);
            }
        }

        private void SendNewPuzzleEmail(MailQueue q)
        { 
            var template = db.MailTemplates.Single(t => t.TemplateName == q.TemplateName);
            var developer = db.Developers.Select(d => new { email=d.Email, name=d.NickName  });
            var post = db.Posts.Include("Developer").Single(p => p.Id == q.ReferTo);

            foreach (var d in developer)
            {
                if (string.IsNullOrEmpty(d.email))
                    continue;

                MailMessage mail = new MailMessage();
                mail.To.Add(d.email);
                mail.IsBodyHtml = true;
                mail.From = fromAddress;
                mail.Subject = string.Format("{0} has just posted a new puzzle", post.Developer.NickName);

                StringBuilder sb = new StringBuilder(template.TemplateContent);
                sb.Replace("$DeveloperName$", d.name );
                ReplacePostTemplateContent(post, sb);
                mail.Body = sb.ToString();

                try
                {
                    smtpService.Send(mail);

                    //success
                    WarOfDev.EF.Mail m = new EF.Mail { 
                        CreatedBy=post.Developer.Id,
                        CreatedOn=DateTime.Now,
                        Id=Guid.NewGuid().ToString(),
                        ModifiedBy=post.Developer.Id,
                        ModifiedOn=DateTime.Now,
                        Status=(int)EnumMailQueueStatus.Sent,
                        TemplateId=template.Id,
                        MailContent=mail.Body,
                        MailSubject=mail.Subject,
                        MailTo=mail.To[0].Address.ToString(),
                        MailFrom=mail.From.Address.ToString()
                    };

                    db.Mails.AddObject(m);
                }
                catch (Exception ex)
                {

                }
                finally
                {
                    q.Status = (int)EnumMailQueueStatus.Sent;
                    db.SaveChanges();

                    mail.Dispose();
                }
            }

          
        }

      



        

        
    }
}
